#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from models import *
from onlineuser.models import getOnlineInfos
from google.appengine.ext import db
from forms import EditPostForm, NewPostForm
import utils
import datetime
from dateutil.parser import parser
import logging

from google.appengine.api import memcache

from counter import PostCounter,TopicCounter,UserCounter
import debt

#g_v={'LBFORUM_TITLE':'LBForum','LBFORUM_SUB_TITLE':'A Clone of FluxBB',}
#g_v={}
class Page:
    lst_obj=[]
    has_previous=False
    has_next = False
    page_size=20
    is_first=True
    
    
def my_get_object_or_404(klass, **kwargs):
    #for key in kwargs.keys:
    key=kwargs.keys()[0]
    q_klass=klass.all()
    q_klass.filter(key+' = ', kwargs.get(key))
    obj=q_klass.get()
    if obj is None:
        raise Http404(' %s with %s=%s not found!' % (klass._meta.object_name,key,str(kwargs.get(key))))
        
    return obj
    

def all(self):
    lst_obj = self.fetch(1000)
    print lst_obj
    return lst_obj
 
def create_admin():
    from django.contrib.auth.models import User
    from counter import UserCounter
    uc=UserCounter()
    seq=uc.inc()
    user = User(key_name='admin', username='admin',email='ego008@gmail.com', first_name='Boss', last_name='Admin',is_active=True, is_staff=True, is_superuser=True)
    user.seq=12
    user.set_password('admin')
    user.save()

def init_topic_counter():
    pass

def get_total_topic_cnt():
    topic_cnt_key="total_topic_cnt"
    topic_cnt= memcache.get(topic_cnt_key)
    if topic_cnt is None:
        counter=TopicCounter()
        topic_cnt = counter.get()
        memcache.add(topic_cnt_key,topic_cnt,60)
    return topic_cnt    

def init_post_counter():
    post_cnt = Post.all().count()
    if post_cnt>0:
        counter=PostCounter()
        counter.reset(post_cnt)
    return post_cnt

        
def get_total_post_cnt():
    post_cnt_key="total_post_cnt"
    post_cnt=debt.get_counter_cnt(PostCounter, post_cnt_key, init_post_counter)
    return post_cnt

def init_total_user_counter():
    user_cnt = User.all().count()
    if user_cnt >0:
        counter=UserCounter()
        counter.reset(user_cnt)
    return user_cnt
    
def get_total_user_cnt():
    user_cnt_key="total_user_cnt"
    user_cnt=debt.get_counter_cnt(UserCounter, user_cnt_key, init_total_user_counter)
    return user_cnt  
    """
    user_cnt= memcache.get(user_cnt_key)
    if user_cnt is None:
        user_cnt = User.all().count()
        memcache.add(user_cnt_key,user_cnt,60)
    return user_cnt  
    """
    
def get_last_registered_user():
    last_registered_user_key="last_registered_user"
    last_registered_user= memcache.get(last_registered_user_key)
    if last_registered_user is None:
        last_registered_user = User.all().order('-date_joined').get()
        memcache.add(last_registered_user_key,last_registered_user,60)
    return last_registered_user  

def get_lst_category():
    lst_category_key="lst_category"
    lst_category= memcache.get(lst_category_key)
    if lst_category is None:
        lst_category = Category.all().order('ordering').fetch(100)
        memcache.add(lst_category_key,lst_category,30)
    return lst_category 


def index(request, template_name="lbforum/index.html"):
    user=User.all().get()
    if user is None:
        create_admin()
        
    #categories = Category.objects.all()
    #categories = Category.all().fetch(100)
    categories = get_lst_category()
    #total_topics = Topic.objects.count()
    #total_topics = Topic.all().count()
    total_topics=get_total_topic_cnt()
    #total_posts = Post.objects.count()
    #total_posts = Post.all().count()
    total_posts = get_total_post_cnt()
    #total_users =  User.objects.count()
    #total_users = User.all().count()
    total_users = get_total_user_cnt()
    #last_registered_user = User.objects.order_by('-date_joined')[0]
    #last_registered_user = User.all().order('-date_joined').get()
    last_registered_user=get_last_registered_user()
    
    ext_ctx = {'categories': categories, 'total_topics': total_topics,
            'total_posts': total_posts, 'total_users': total_users,
            'last_registered_user': last_registered_user}
    ext_ctx.update(getOnlineInfos(True))
    """
    import os
    print "xxx"
    print os.getcwd()
    
    C:\Users\randliu\workspace\WordTalk\common\appenginepatch
    """
    #ext_ctx.update(g_v)
    #print RequestContext(request)
    for category in categories:
        #lst_forum= category.forum_set.fetch()
        #category.forum_set.all=all
        #setattr(category.forum_set, 'all', new.instancemethod(all, None, category.forum_set))
        #category.forum_set.all=category.forum_set.fetch(1000)
        category.lst_forum=category.forum_set.fetch(1000)
        pass
    return render_to_response(template_name, ext_ctx, RequestContext(request))


def forum(request, forum_slug, template_name="lbforum/forum.html"):
    
    forum = my_get_object_or_404(Forum, slug = forum_slug)
    start = request.GET.get('s', '')

    page = Page()
    
    
    
    datetime_date = None
    n=len(start)
    
    sticky_topics=[]
    
    if start is None or n==0:
        q_sticky_topics=forum.topic_set.filter('sticky = ',True)
        #q_sticky_topics=Topic.all().filter('forum= ', forum.key()).filter('sticky= ', True)
        sticky_topics = q_sticky_topics.fetch(20)
        #logging.log(logging.INFO, "got %d sticky_topics"%len(sticky_topics))

    
    
    if start is not None and n>0:
        page.has_previous=True
        date_str=start.encode('ascii')
        #2010-07-15 10:54:46.312000
        #datetime.datetime.strptime(date_str,'%Y%m%dT%H:%M:%S')
        #date=datetime.datetime.strptime(date_str,'%Y-%m-%d %H:%M:%S.%f')
        p = parser()
        datetime_date = p.parse(date_str)
    else:
        page.has_previous=False
        
    
    
    q_topics=forum.topic_set
    if datetime_date is not None:
        """
                        �޸ķ�ҳ���� 2010/11/21
        """
        #q_topics.filter('last_reply_on >= ', datetime_date)
        
        q_topics.filter('last_reply_on <= ', datetime_date)
        q_topics.filter('sticky =',False)
    
    
    
        
    q_topics=q_topics.order('-last_reply_on')
    
    #if len(sticky_topics) ==0:
    #    topics=q_topics.fetch(page.page_size+1)
    #else:
    topics=q_topics.fetch(page.page_size+len(sticky_topics)+1)
    #ai...delete sticky topics.
    #I dont know why they are here
    topic_cnt=len(topics)
    i=0
    while i< topic_cnt:
        if topics[i].sticky is True:
            del topics[i]
            topic_cnt=topic_cnt -1
        else:
            i=i+1
            
            
    topics_cnt=len(topics)
    
    """
    #fetching sticky topics
    q_topics=forum.topic_set
    q_topics.filter('sticky = ',True)
    sticky_topics=q_topics.fetch(20)
    """
    """
    #insert sticky topics 
    if start is None or n==0:
        for topic in sticky_topics:
            #del topics[-1]
            topics.insert(0,topic)
    """
    """
    logging.log(logging.INFO, "total %d topics in this page"%len(topics))
    for topic in topics:
        logging.log(logging.INFO, "title: %s "%topic.subject)
    
    logging.info("ffffffffffffffffffffffffff")
    
    for topic in sticky_topics:
        logging.log(logging.INFO, "sticky title: %s "%topic.subject)
    
    logging.log(logging.INFO, "total %d sticky topics in this page"%len(sticky_topics))
    """
    topics=sticky_topics+topics
    
    guard=None
    if topics_cnt > page.page_size:
        page.has_next=True
        guard=topics[-1]
        page.start=guard.last_reply_on
        del topics[-1]
        page.is_first=False
    
    
    
    ext_ctx = {'forum': forum, 'topics': topics,'page':page,'topics_cnt':topics_cnt,'guard':guard,}
    
    
    return render_to_response(template_name, ext_ctx, RequestContext(request))


#@login_required
def new_post(request, forum_id=None, topic_id=None, form_class=NewPostForm, \
        template_name='lbforum/post.html'):
    qpost = topic = forum = first_post = preview = None
    show_subject_fld = True 
    post_type = _('topic')
    if forum_id:
        #forum = get_object_or_404(Forum, pk=forum_id)
        
        #forum = db.get(forum_id)
        forum=Forum.all().filter(' slug = ',forum_id).get()
        
    if topic_id:
        post_type = _('reply')
        #topic = get_object_or_404(Topic, pk=topic_id)
        #topic =db.get(topic_id)
        seq = int(topic_id)
        topic = utils.get_topic_by_seq(seq)
        forum = topic.forum
        #first_post = topic.post_set.order_by('created_on').select_related()[0]
        #first_post = topic.post_set.fetch(1000)
        first_post = topic.post_set.order('created_on').get()
        #fist_post=[topic.post_set.get()]
        show_subject_fld = False
    if request.method == "POST":
        form = form_class(request.POST, user=request.user, forum=forum, topic=topic, \
                ip=request.META['REMOTE_ADDR'])
        preview = request.POST.get('preview', '')
        valid=form.is_valid()
        has_submit=request.POST.get('submit', '')
        #if form.is_valid() and request.POST.get('submit', ''):
        if valid and has_submit:
            post = form.save()
            PostCounter().inc()
            #post = form.put()
            if topic:
                return HttpResponseRedirect(post.get_absolute_url_ext())
            else:
                return HttpResponseRedirect(reverse("lbforum_forum", args=[forum.slug]))
    else:
        initial={}
        qid = request.GET.get('qid', '')
        if qid:
            #qpost = get_object_or_404(Post, id=qid)
            #qpost=db.get(qid)
            qpost=utils.get_post(topic_id, qid)
            if qpost is None:
                raise Http404(' %s with %s=%s not found!' % ('Post','key',qid))
            
            initial['message'] = "[quote=%s]%s[/quote]" % (qpost.posted_by.username, qpost.message)
        form = form_class(initial=initial)
    ext_ctx = {'forum':forum, 'form':form, 'topic':topic, 'first_post':first_post, \
            'post_type':post_type, 'preview':preview, 'show_subject_fld': show_subject_fld}
    #ext_ctx['unpublished_attachments'] = request.user.attachment_set.all().filter(activated=False)
    q_attach= request.user.attachment_set
    q_attach.filter('activated =', False)
    ext_ctx['unpublished_attachments']=q_attach.fetch(1000)
    ext_ctx['is_new_post'] = True
    
    return render_to_response(template_name, ext_ctx, RequestContext(request))

def topic(request, topic_id, template_name="lbforum/topic.html"):
    #topic = get_object_or_404(Topic, id = topic_id)
    #topic =db.get(topic_id)
    #topic= Topic.get_by_key_name("t_%s"%topic_id)
    
    topic = utils.get_topic_by_seq(topic_id)
    if topic is None:
        raise Http404(' %s with %s=%s not found!' % ("Topic","key",topic_id))
    topic.num_views += 1
    topic.save()
    #posts = topic.post_set.order_by('created_on').select_related()
    #posts=topic.post_set.fetch(1000)
    #ext_ctx = {'topic': topic, 'posts': posts}
    
    
    posts_q=topic.post_set
    #ext_ctx = {'topic': topic, 'posts': posts_q}
    ext_ctx = {'topic': topic, 'Post':Post,}
    
    page = request.GET.get('page')
    if page is None:
        page="1"
    request.page=page
    return render_to_response(template_name, ext_ctx, RequestContext(request))

@login_required
def user_posts(request, user_id, template_name='lbforum/user_posts.html'):
    #view_user = User.objects.get(pk=user_id)
    view_user=db.get(user_id)
    #posts = view_user.post_set.order_by('-created_on').select_related()
    posts=view_user.post_set.fetch(1000)
    return render_to_response(template_name, {'posts': posts, 'view_user': view_user}, RequestContext(request))
    

@login_required
def user_topics(request, user_id, template_name='lbforum/user_topics.html'):
    #view_user = User.objects.get(pk=user_id)
    view_user=db.get(user_id)
    #topics = view_user.topic_set.order_by('-created_on').select_related()
    topics =view_user.topic_set.fetch(1000)
    return render_to_response(template_name, {'topics': topics, 'view_user': view_user}, \
            RequestContext(request))    
    
    
@login_required
def edit_post(request, topic_seq,seq_in_topic, form_class=EditPostForm, template_name="lbforum/post.html"):
    topic = forum = first_post = preview = None
    post_type = _('topic')
    #edit_post = get_object_or_404(Post, id=post_id)
    #edit_post=db.get(post_id)
    post_key_name = "t_%s_p_%s"%(topic_seq,seq_in_topic)
    #edit_post = Post.get_by_key_name(post_key_name)
    edit_post=debt.get_obj(Post, post_key_name)
    if edit_post is None:
                raise Http404(' %s with %s=%s not found!' % ('post','key',post_key_name))

    if request.method == "POST":
        form = form_class(instance=edit_post, user=request.user, data=request.POST,key_name=post_key_name)
        preview = request.POST.get('preview', '')
        if form.is_valid() and request.POST.get('submit', ''):
            edit_post = form.save()
            return HttpResponseRedirect('../')
    else:
        form = form_class(instance=edit_post)
    ext_ctx = {'form':form, 'topic':edit_post.topic, 'forum':edit_post.topic.forum, \
            'post_type':post_type, 'preview':preview}
    
    #ext_ctx['unpublished_attachments'] = request.user.attachment_set.all().filter(activated=False)
    q_attachments = request.user.attachment_set.filter('activated = ',False)
    
    ext_ctx['unpublished_attachments'] =q_attachments.fetch(1000) 
    ext_ctx['show_subject_fld'] = edit_post.topic_post
    return render_to_response(template_name, ext_ctx, RequestContext(request))
    
def markitup_preview(request, template_name="lbforum/markitup_preview.html"):
    return render_to_response(template_name, {'message': request.POST['data']}, \
            RequestContext(request))

def post(request, topic_seq,seq_in_topic):
    #post = get_object_or_404(Post, id=post_id)
    #post= db.get(post_id)
    #post= utils.get_post(topic_seq, seq_in_topic)
    post_key_name="t_%s_p_%s"%(topic_seq,seq_in_topic)
    post=debt.get_obj(Post, post_key_name)
    if post is None:
        raise Http404(' %s with %s=%s not found!' % ("Post","key",post_key_name))
    
    return HttpResponseRedirect(post.get_absolute_url_ext())        